#include "KcPickGrayPhoto.h"
#include <QImage>
#include <memory>

void KcPickGrayPhoto::doCalc_(const QString& filePath, void* fileObj)
{
    auto img = (QImage*)(fileObj);
    tryEmitResult_(filePath, isGrayscale_(*img));
}

bool KcPickGrayPhoto::isGrayscale_(const QImage& img) const
{
    if (img.isGrayscale()) // 文件为灰度格式，返回true
        return true;
    else if (pixTol_ == 0 && grayTol_ == 0) // 全灰度判定
        return img.allGray();

    // 缩放到小尺寸进行判决，以加快判定速度
    // TODO: 是否能提升整体速度？
    const QImage* realImg = &img;
    QImage scaledImg;
    if (img.width() > 128 || img.height() > 128) {
        scaledImg = img.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        realImg = &scaledImg;
    }

    // 逐个像素判断是否灰度值
    int grays(0); // 灰度像素个数
    int ungrays(0);
    double pixels = realImg->width() * realImg->height();
    int ungrayline = grayTol_ * pixels;
    int grayline = pixels - ungrayline;
    auto tol = pixTol_ * 255.;
    for (int i = 0; i < realImg->width(); i++) {
        for (int j = 0; j < realImg->height(); j++){
            auto clr = realImg->pixel(i, j);
            int r(qRed(clr)), g(qGreen(clr)), b(qBlue(clr));
            if (qAbs(r-b) <= tol && qAbs(r-g) <= tol && qAbs(b-g) <= tol)
                ++grays;
            else
                ++ungrays;

            // 是否提前结束
            if (grays >= grayline)
                return true;
            else if (ungrays >= ungrayline)
                break;
        }
    }

    return false;
}
